package com.cskaoyan.config;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

/**
 * @author stone
 * @date 2022/04/09 10:51
 */
@Configuration
public class ShiroConfiguration {


    /*ShiroFilter*/
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();

        filter.setSecurityManager(securityManager);
        //filter和url之间的映射关系 → filter是谁，作用范围是什么
        //Shiro提供了可以直接使用的Filter → anon、authc、perms

        //有序的链 → Map → LinkedHashMap
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //key是url，value是filter
        //filterChainDefinitionMap.put("/**", "anon");
        //SpringMVC作业：如果是login请求，就放行
        filterChainDefinitionMap.put("/admin/auth/login", "anon");
        filterChainDefinitionMap.put("/admin/auth/info", "anon");
        //认证的请求通常放在匿名的请求后面
        filterChainDefinitionMap.put("/**", "authc");
        filter.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return filter;
    }

    /*SecurityManager*/
    @Bean
    public DefaultWebSecurityManager securityManager(DefaultWebSessionManager sessionManager,
                                                     MarketRealm marketRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setSessionManager(sessionManager);

        //认证器和授权器 → 可以设置，也可以不设置;不过不设置，会使用默认的认证器和授权器
        //默认的认证器是ModularRealmAuthenticator，默认的授权器ModularRealmAuthorizer
        //默认的认证器和默认的授权器里需要使用realm → realm来源于SecurityManager

        securityManager.setRealm(marketRealm);//给默认的认证器和默认的授权器提供realm

        return securityManager;
    }

    /*SessionManager*/
    @Bean
    public DefaultWebSessionManager sessionManager() {
        //跨域会导致Session发生变化，需要保证认证前后使用同一个Session，避免信息丢失
        return new MarketSessionManager();
    }

    /*Realm*/
    /*@Bean
    public MarketRealm marketRealm() {
        return new MarketRealm();
    }*/

    //注册一个advisor → aspectjweaver
    //Handler方法上使用@RequiresPermission
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
